package com.wu.http.server;

import com.wu.javax.servlet.http.HttpSession;
import com.wu.threadPool.ThreadPoolManager;
import com.wu.util.PackageScan;
import com.wu.util.TomcatUtil;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static com.wu.constant.Constant.ROOT_PACKAGE_NAME;
import static com.wu.constant.Constant.logger;


public class Main {

    /**
     * 创建ScheduledExecutorService的实例
     */
    private final ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(4);

    public static void main(String[] args) throws Exception {
        new Main().startServer();
    }

    private static Map<String, String> MAPPING_MAP = new HashMap<>();

    /**
     * 获取  contentType 映射
     *
     * @return Map<String, String>
     */
    public static Map<String, String> getMappingMap() {
        return MAPPING_MAP;
    }

    static {
        try {
            //读取文件后缀名映射
            MAPPING_MAP = TomcatUtil.parseWebConfig();
            //加载包扫描
            PackageScan.searchClass(ROOT_PACKAGE_NAME);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 启动服务
     *
     * @throws Exception
     */
    private void startServer() throws Exception {
        //定时清理Session
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            synchronized (Main.this) {
                Map<String, HttpSession> sessionMap = ((MyHttpSessionContext) MyHttpSessionContext.getInstance()).getSessions();
                for (Map.Entry<String, HttpSession> entry : sessionMap.entrySet()) {
                    HttpSession session = entry.getValue();
                    long start = session.getLastAccessedTime();
                    long end = System.currentTimeMillis();
                    try {
                        if (end - start > (long) TomcatUtil.getSessionOverdueTime() * 60 * 1000) {
                            sessionMap.remove(session.getId());
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }, 10, 10, TimeUnit.SECONDS);
        ServerSocket serverSocket;
        //从xml中获取端口  9000
        int port = TomcatUtil.parseServerXml();
        //获取 虚拟机可用的最大处理器数
        int cpuCount = Runtime.getRuntime().availableProcessors();
        ThreadPoolManager threadPoolManager = new ThreadPoolManager(cpuCount, null);
        try {
            serverSocket = new ServerSocket(port);
            logger.debug("tomcat server is starting, and listening to port :" + serverSocket.getLocalPort());
        } catch (IOException var6) {
            logger.error("tomcat server's port :" + port + " is already in use...");
            return;
        }
        while (true) {
            try {
                //一直等待请求的到来，然后把请求交给线程池处理，最后线程池执行任务
                Socket socket = serverSocket.accept();
                logger.debug("a client " + socket.getInetAddress() + " is connecting to tomcat server....");
                threadPoolManager.process(new TaskService(socket));
            } catch (IOException e) {
                logger.error("client is down, cause:" + e.getMessage());
            }
        }
    }
}
